package com.OjSystem.friend.service.user.impl;

import cn.hutool.core.util.RandomUtil;
import com.OjSystem.common.core.errorcode.modules.ojfriend.FriendServiceErrorCode;
import com.OjSystem.common.core.exception.friend.FriendServiceException;
import com.OjSystem.common.message.service.AliMessageService;
import com.OjSystem.common.redis.Constants.RedisConstants;
import com.OjSystem.common.redis.service.RedisService;
import com.OjSystem.common.security.Enum.LoginUserEnum;
import com.OjSystem.common.security.service.TokenService;
import com.OjSystem.friend.Enum.user.UserStatus;
import com.OjSystem.friend.domain.DTO.UserMessageDTO;
import com.OjSystem.friend.domain.User;
import com.OjSystem.friend.mapper.user.UserMapper;
import com.OjSystem.friend.service.user.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private AliMessageService aliMessageService;

    @Autowired
    private RedisService redisService;

    @Value("${sms.code-expiration:5}")
    private Long phoneCodeExpiration;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TokenService tokenService;


    /**
     * 发送短信验证码
     *
     * @param userMessageDTO
     * @return
     */
    @Override
    public boolean sendMessage(UserMessageDTO userMessageDTO) {
        // 校验数据
        if (!StringUtils.hasText(userMessageDTO.getPhone())) {
            throw new FriendServiceException(FriendServiceErrorCode.LOGIN_PHONE_IS_EMPTY);
        }
        if (!checkPhone(userMessageDTO.getPhone())) {
            throw new FriendServiceException(FriendServiceErrorCode.PHONE_FORMAT_IS_ERROR);
        }
        Long remainTime = redisService.getExpire(RedisConstants.PHONE_CODE_KEY + userMessageDTO.getPhone(), TimeUnit.MINUTES);
        if (remainTime != -2L && (phoneCodeExpiration * 60 - remainTime) < 60) {
            throw new FriendServiceException(FriendServiceErrorCode.SEND_MESSAGE_ERROR);
        }

        // 生成随机验证码
        String code = RandomUtil.randomNumbers(6);
        System.out.println(phoneCodeExpiration);

        // 存储到redis中
        redisService.setCacheObject(RedisConstants.PHONE_CODE_KEY + userMessageDTO.getPhone(), code, phoneCodeExpiration, TimeUnit.MINUTES);

        // 发送短信验证码
        return aliMessageService.sendMobileCode(userMessageDTO.getPhone(), code);
    }


    /**
     * 校验手机号格式
     *
     * @param phone
     * @return
     */
    public static boolean checkPhone(String phone) {
        Pattern regex = Pattern.compile("^1[2|3|4|5|6|7|8|9][0-9]\\d{8}$");
        Matcher m = regex.matcher(phone);
        return m.matches();
    }


    /**
     * 用户登录
     *
     * @param userMessageDTO
     * @return
     */
    @Override
    public String login(UserMessageDTO userMessageDTO) {
        // 校验基本数据
        if (!StringUtils.hasText(userMessageDTO.getPhone())) {
            throw new FriendServiceException(FriendServiceErrorCode.PHONE_NUMBER_IS_EMPTY);
        }
        if (!StringUtils.hasText(userMessageDTO.getCode())) {
            throw new FriendServiceException(FriendServiceErrorCode.CODE_IS_EMPTY);
        }

        // 校验验证码
        String verificationCode = redisService.getCacheObject(RedisConstants.PHONE_CODE_KEY + userMessageDTO.getPhone(), String.class);
        if (!StringUtils.hasText(verificationCode)) {
            throw new FriendServiceException(FriendServiceErrorCode.VERIFICATION_CODE_IS_EMPTY);
        }
        if (!verificationCode.equals(userMessageDTO.getCode())) {
            throw new FriendServiceException(FriendServiceErrorCode.VERIFICATION_CODE_IS_ERROR);
        }


        // 判断是否是新用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, userMessageDTO.getPhone());
        User user = userMapper.selectOne(queryWrapper);

        // 如果是新用户
        if (user == null) {
            user = new User();
            user.setPhone(userMessageDTO.getPhone());
            user.setStatus(UserStatus.NORMAL.getCode());
            userMapper.insert(user);
        }

        // 返回token
        return tokenService.createToken(user.getUserId(), LoginUserEnum.NORMAL.getCode(), user.getNickName());
    }
}
